package com.javandad.app.client;

import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.javandad.app.client.cells.GroupCell;
import com.javandad.app.client.cells.UserCell;
import com.javandad.app.shared.entity.User;
import com.javandad.app.shared.entity.UserGroup;

// Friends'n'Groups
public class FnG implements EntryPoint {

	DecoratedTabPanel fng;
	VerticalPanel friends;
	CellList<User> friendsList;
	VerticalPanel groups;
	CellList<UserGroup> groupsList;
	TextBox newGroup;

	NetworkServiceAsync network;

	RootPanel fngContainer;
	String username;
	String view;

	@Override
	public void onModuleLoad() {
		fngContainer = RootPanel.get("fngContainer");
		if(fngContainer == null)
			return;
		network = GWT.create(NetworkService.class);
		username = getContainerParameter("username");
		view = getContainerParameter("view");
		initGUI();
		fng.selectTab(0);
	}

	private String getContainerParameter(String name) {
		String value = fngContainer.getElement().getAttribute(name);
		if (value.isEmpty())
			value = null;
		return value;
	}

	public void initGUI() {
		fng = new DecoratedTabPanel();

		fng.setWidth("100%");
		fng.setHeight("100%");
		fng.add(createFriendsTab(), "Friends");
		fng.add(createGroupsTab(), "Groups");

		RootPanel.get("fngContainer").add(fng);
	}

	public Widget createFriendsTab() {
		friends = new VerticalPanel();
		friendsList = new CellList<User>(new UserCell());
		final SingleSelectionModel<User> selectionModel = new SingleSelectionModel<User>();
		friendsList.setSelectionModel(selectionModel);
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			public void onSelectionChange(SelectionChangeEvent event) {
				User user = selectionModel.getSelectedObject();
				Window.open("home.jsp?"+CodesvrParam.getCodesvrParam()+"&view="+user.getUsername(), "_self", "");
			}
		});
		friends.add(friendsList);
		String look = (view != null ? view : username);
		network.getFriends(look, new AsyncCallback<List<User>>() {
			public void onFailure(Throwable caught) {
				friends.add(new Label("Error retrieving friends list!"));
			}

			public void onSuccess(List<User> result) {
				friendsList.setRowData(result);
			}
		});
		return friends;
	}

	public Widget createGroupsTab() {
		groups = new VerticalPanel();
		groupsList = new CellList<UserGroup>(new GroupCell());
		final SingleSelectionModel<UserGroup> selectionModel = new SingleSelectionModel<UserGroup>();
		groupsList.setSelectionModel(selectionModel);
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
			public void onSelectionChange(SelectionChangeEvent event) {
				UserGroup group = selectionModel.getSelectedObject();
				String href = "group.jsp?"+CodesvrParam.getCodesvrParam()+"&group="+group.getGroupURL()+(view != null ? "&view="+view : "");
				Window.open(href, "_self", "");
			}
		});
		groups.add(groupsList);
		updateGroups();
		if(username != null)
		{
			groups.add(new HTML("<hr />"));
			groups.add(new Label("create or join group:"));
			newGroup = new TextBox();
			groups.add(newGroup);
			newGroup.addKeyUpHandler(new KeyUpHandler() {
				public void onKeyUp(KeyUpEvent event) {
					if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
						final String groupname = newGroup.getText();
						network.createOrJoinGroup(username, groupname, new AsyncCallback<Boolean>() {
	
							@Override
							public void onFailure(Throwable caught) {
								Window.alert(caught.getMessage());
							}
	
							@Override
							public void onSuccess(Boolean result) {
								if(result)
									Window.alert("Group "+groupname+" created.");
								else
									Window.alert("Joined group "+groupname+".");
								updateGroups();
							}});
					}
				}});
		}
		return groups;
	}
	
	private void updateGroups()
	{
		String look = (view != null ? view : username);
		network.getGroups(look, new AsyncCallback<List<UserGroup>>() {
			public void onFailure(Throwable caught) {
				groups.add(new Label("Error retrieving groups list!"));
			}
			public void onSuccess(List<UserGroup> result) {
				groupsList.setRowData(result);
			}
		});
	}

}
